import Control.Concurrent
import Control.Concurrent.STM (STM, TVar, atomically, newTVar, readTVar, writeTVar,retry)
import Control.Concurrent.Async (mapConcurrently_, replicateConcurrently_)

transfer :: TVar Int -> TVar Int -> Int -> STM ()
transfer from to amount = do
    balanceFrom <- readTVar from
    balanceTo <- readTVar to
    if balanceFrom < amount
        then retry  -- 余额不足，等待并重试
        else do
            writeTVar from (balanceFrom - amount)
            writeTVar to (balanceTo + amount)


stm_test :: IO ()
stm_test = do
    accountA <- atomically $ newTVar 1000
    accountB <- atomically $ newTVar 0

    -- 并发执行并自动等待完成
    mapConcurrently_ (\amt -> atomically $ transfer accountA accountB amt) 
                    [50, 30, 60, (-70), 29]  -- 负数表示反向转账

    -- 直接读取结果（此时所有线程已结束）
    balA <- atomically $ readTVar accountA
    balB <- atomically $ readTVar accountB
    putStrLn $ "Final balances - A: " ++ show balA ++ ", B: " ++ show balB